﻿/*
 * ======================================================================
 *                           Modern Warfare3 Launcher
 * Copyright 2011-2012
 * Developer:Pooya parsa
 * Email:pingsft@gmail.com
 * You are ALLOWED:
 * -Read source code
 * -Use some part of source code with Full name and email of developer
 * -Release your own mod with name of develepor
 * You are NOT ALLOWD:
 * -Add cracked version of Mw3
 * -Release modified version as MW3Launcher
 * -Mirror Sourcecode
 * -Use source code without name of developer
 * Thank you for your attention
 * ======================================================================
 * */
using System;
using System.CodeDom.Compiler;
using System.ComponentModel;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading;
using System.Windows;
using System.Threading;
using System.Windows.Forms;
using MW3Launcher;
namespace MW3Launcher
{
    public partial class RunProc : Form
    {
        //Private
        private bool _contentLoaded;
        private bool canclose;
        private bool initialized;
        private Mutex mutex;
        private IntPtr thread;
        private System.Windows.Forms.Timer dispatcherTimer;

        //Properties
        public string Commandargs { get; set; }
        public string ExecutableName { get; set; }


        //Initializer
        public RunProc()
        {
            InitializeComponent();
            notifyIcon1.ShowBalloonTip(10);
            this.dispatcherTimer = new System.Windows.Forms.Timer();
            this.dispatcherTimer.Interval = 1;
            //Events
            this.dispatcherTimer.Tick += new EventHandler(dispatcherTimer_Tick);
            this.Load += new EventHandler(RunProc_Load);
            this.FormClosing += new FormClosingEventHandler(RunProc_FormClosing);
        }

        //Events
        void RunProc_Load(object sender, EventArgs e)
        {
            this.initialized = false;
            this.dispatcherTimer.Start();
            if (this.ExecutableName == "iw5mp_server.exe")
                this.RunningLabel.Text = "Running dedicated server, a moment please.";
        }

        void RunProc_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (!this.canclose)
            {
                e.Cancel = true;
            }
            else
            {
            }
        }

        void dispatcherTimer_Tick(object sender, EventArgs e)
        {
            if (!this.initialized)
            {
                this.initialized = true;
                threadi();
                this.dispatcherTimer.Interval = 5;
            }
            else
            {
                CONTEXT lpContext = new CONTEXT();
                try
                {
                    if (this.ExecutableName == "iw5mp_server.exe")
                    {
                        this.mutex.Close();
                        this.canclose = true;
                        iClose();
                    }
                    if (!Win32Apis.GetThreadContext(this.thread, ref lpContext))
                    {
                        this.mutex.Close();
                        this.canclose = true;
                        iClose();
                    }
                }
                catch (Exception)
                {
                    try
                    {
                        this.mutex.Close();
                        this.canclose = true;
                        iClose();
                    }
                    catch (Exception)
                    {
                        this.canclose = true;
                        iClose();
                    }
                }
            }
        }

        //Functions
        public void iClose()
        {
            notifyIcon1.Visible = false;
            notifyIcon1.BalloonTipText = "";
            Hide();
            //this.Close();        
        }
        public static int BytesToInt(byte[] input)
        {
            return int.Parse(input[3].ToString("X2") + input[2].ToString("X2") + input[1].ToString("X2") + input[0].ToString("X2"), NumberStyles.HexNumber);
        }

        public static int IndexOf(byte[] arrayToSearchThrough, byte[] patternToFind)
        {
            if (patternToFind.Length <= arrayToSearchThrough.Length)
            {
                for (int i = 0; i < (arrayToSearchThrough.Length - patternToFind.Length); i++)
                {
                    bool flag = true;
                    for (int j = 0; j < patternToFind.Length; j++)
                    {
                        if (arrayToSearchThrough[i + j] != patternToFind[j])
                        {
                            flag = false;
                            break;
                        }
                    }
                    if (flag)
                    {
                        return i;
                    }
                }
            }
            return -1;
        }

        private static int Round1000(int a)
        {
            return (((a / 0x1000) + (((a % 0x1000) > 0) ? 1 : 0)) * 0x1000);
        }

        private void threadi()
        {
            STARTUPINFO lpStartupInfo = new STARTUPINFO();
            PROCESS_INFORMATION lpProcessInformation = new PROCESS_INFORMATION();
            byte[] sourceArray = File.ReadAllBytes(this.ExecutableName);
            byte[] destinationArray = new byte[4];
            Array.Copy(sourceArray, 60, destinationArray, 0, 2);
            byte[] buffer3 = new byte[4];
            int num = BytesToInt(destinationArray);
            int sourceIndex = num + 0x128;
            int num3 = num + 300;
            int num4 = num + 0x130;
            int num5 = num + 0x134;
            Array.Copy(sourceArray, num4, buffer3, 0, 4);
            num4 = BytesToInt(buffer3);
            Array.Copy(sourceArray, num5, buffer3, 0, 4);
            num5 = BytesToInt(buffer3);
            Array.Copy(sourceArray, num3, buffer3, 0, 4);
            num3 = BytesToInt(buffer3) + 0x400000;
            Array.Copy(sourceArray, sourceIndex, buffer3, 0, 4);
            sourceIndex = Round1000(BytesToInt(buffer3));
            int index = IndexOf(sourceArray, Encoding.ASCII.GetBytes("steam_api.dll"));
            if ((index < num5) && (index > (num5 + num4)))
            {
                MessageBox.Show("Cannot find steam_api.dll string in executable, make sure you have the proper original files!");
            }
            else
            {
                int num7 = index - num5;
                if (!Win32Apis.CreateProcess(this.ExecutableName, this.Commandargs, IntPtr.Zero, IntPtr.Zero, false, 0x204, IntPtr.Zero, null, ref lpStartupInfo, out lpProcessInformation))
                {
                    MessageBox.Show("Cannot create process!");
                }
                else
                {
                    uint num8;
                    UIntPtr ptr;
                    uint num9;
                    this.thread = lpProcessInformation.hThread;
                    Win32Apis.VirtualProtectEx(lpProcessInformation.hProcess, new IntPtr(num3), new UIntPtr((uint)sourceIndex), 0x40, out num8);
                    Win32Apis.WriteProcessMemory(lpProcessInformation.hProcess, new IntPtr(num3 + num7), Encoding.ASCII.GetBytes("teknomw3.dll"), 13, out ptr);
                    Win32Apis.VirtualProtectEx(lpProcessInformation.hProcess, new IntPtr(num3), new UIntPtr((uint)sourceIndex), num8, out num9);
                    if (ptr == ((UIntPtr)0))
                    {
                        MessageBox.Show("Cannot write to process memory!");
                        Win32Apis.TerminateProcess(lpProcessInformation.hProcess, 0);
                        Win32Apis.TerminateThread(lpProcessInformation.hThread, 0);
                    }
                    else
                    {
                        uint num10 = lpProcessInformation.dwProcessId ^ 0x57;
                        this.mutex = new Mutex(false, "TeknoMW3" + num10.ToString("X8"));
                        Win32Apis.ResumeThread(lpProcessInformation.hThread);
                    }
                }
            }
        }


    }
}
